home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-08-10 | 56.0 KB | 1,103 lines |
- #!/bin/sh
- # to extract, remove the header and type "sh filename"
- if `test ! -d ./doc`
- then
- mkdir ./doc
- echo "mkdir ./doc"
- fi
- if `test ! -s ./doc/TYLMAN.05`
- then
- echo "writing ./doc/TYLMAN.05"
- cat > ./doc/TYLMAN.05 << 'E_O_F'
- \chapter{When Things Go Wrong}
- Despite the best of examples and directions about careful typing of
- \hbox{|\special|} strings, there are times when \TT will
- get upset and complain about some situation or input. Fortunately, \TT can
- continue from most of them (like missing or incorrect parameters), and
- just report them in the |.tlog| log-file\index{{\tt .tlog}
- file}\index{{\TT}, {\tt .tlog} log-file}
- for you.\index{{\TT}, error handling} An example run of \TT might look
- like:\filbreak
- \begin{verbatim}
- >textyl
- This is TeXtyl, version ...
- DVI-input File Name: myfile.dvi
- DVI-output File Name :
- (different than input name)[default of myfile.tyl]
- [1] [?2]
- Output written on myfile.tyl
- Log written on myfile.tlog
- Some error(s) occurred. Please check Logfile for details.
- Assume that the outputfile is incorrect
- \end{verbatim}\filbreak
- Rather than annoy you at the terminal with long error messages, \TT puts a
- |?|\index{{\tt ?} flag} mark to indicate that some error happened. Since it wrote the
- |.tyl|\index{{\tt .tyl} file} output file, \TT must have recovered\index{{\TT}, error recovering}
- well enough to finish its job,
- but the output probably does not look right. The |.tlog| file might look
- like\filbreak
- \begin{verbatim}
- This is TeXtyl, Version blah...
- Reading File: myfile.dvi
- [1] [
- Error in fig# 1 on page 2
- Arc Thickness not found. Setting to 1
- 2]
- Output written on myfile.tyl
- Log written on myfile.tlog
- \end{verbatim}\filbreak
- \noindent which was just a missing parameter to the |\special{tyl arc ...}| string.
- You will have to re-edit the file and insert the correct thickness.
- \index{{\TT}, error messages}
- All the error messages that are written to the |.tlog| file try to pin down
- the error to the figure number on the error-containing page. These
- references to the position of the error
- come from the $n^{\rm th}$ figure on the page (the $n$ count is relative to
- each page, and starts from 1), and the page number is from {\TeX}'s
- |\count0| register that enumerates pages.
- Sometimes \TT
- cannot always determine the exact figure on the page
- (e.g., if we forget to close a figure definition with an
- |endfigure|), and so estimates at least the bad page in question. For the most
- part, the error is a just missing parameter,
- or a bad parameter to a |\special| string being read by \TTN.\par\filbreak
-
- However, there are a larger number of errors that \TT
- found ``surprising'' \index{errors, internal}\index{surprise errors}
- and so marks these errors on your screen as |?! |.\index{{\tt ?!} flag} Most
- of these internal errors are based on the functionality of {\DVI}type
- concerning {\smallrm TFM} information, and the structure and commands
- of the {\DVI} file being read. \TTN, like {\DVI}type, will complain, and
- possibly roll over and die gracefully.\par\filbreak
-
- The other ``surprising'' errors that \TT might complain about are really
- internal to \TTN, and constitute a bug,\index{{\TT}, simple problem} or just a
- compile-time constant that is too small. These easily-fixed surprises are
- \begin{itemize}
- \item |too many dvistrings|. This page required more {\DVI} bytes than usual.
- Have your local maintainer\index{local
- maintainer} increase the size of the internal buffer used for storing a
- page's {\DVI} bytes.
- \item |too many spline segments required|. The spline you tried to set might
- be too large/long for the space allocated for a spline's description.
- That size is also a compile-time constant. \TT
- will reduce the number of control points that it interpolates so that you
- can at least get the output, and so that it does not die ungracefully.
- \item |figure definition not closed at end of page|. You forgot a
- |\special{tyl endfigure}| command in some figure definition on the page. \TT
- will not typeset that figure, and will go on to the next page.
- \end{itemize}\par\filbreak
- There are also some down-deep errors that could potentially (although
- doubtfully) show up. These
- are probably some error in the vector fonts being referenced by
- \TTN.\index{{\TT}, serious problems}
- \begin{itemize}
- \item |min radius of vector font is zero|. The referenced vector font's
- {\smallrm TFM} information reported that the font's radius size
- is smaller than it was designed to be.
- \TT will make a temporary fix so that it can
- continue, but the output figure will be wrong. Have the local maintainer
- re-check the vector fonts.
- \item |bad dydx|. This is a rare problem. Somewhere, the code to typeset a
- diagonal line segment referenced an impossible $dy/dx$ combination, and cannot find
- any vector character to fit. \TT will continue, but you may see a
- tiny glitch in your figure.
- \item |dx is too big/small|, |dy is too big/small|. This is a problem. For
- some reason, a distance was referenced that is out of the range of the
- 32-bit representation of integers. This really should never happen.
- \end{itemize}
-
- For the most part, \TT can recover from errors that it encounters, and give
- a brief summary in the |.tlog| file. Other errors have to do with {\smallrm
- TFM} file information, and are outside the scope of \TT to handle
- gracefully. The most serious ``surprise'' errors are bugs, and you should
- report them directly to me with a copy of the |.tex| file, or at least a
- detailed printout from {\DVI}type of the |.dvi| file processed by \TTN.\par
-
- \Makeodd
- E_O_F
- else
- echo "will not over write ./doc/TYLMAN.05"
- fi
- chmod 644 ./doc/TYLMAN.05
- if [ `wc -c ./doc/TYLMAN.05 | awk '{printf $1}'` -ne 5308 ]
- then
- echo `wc -c ./doc/TYLMAN.05 | awk '{print "Got " $1 ", Expected " 5308}'`
- fi
- if `test ! -s ./doc/TYLMAN.06`
- then
- echo "writing ./doc/TYLMAN.06"
- cat > ./doc/TYLMAN.06 << 'E_O_F'
- \chapter{Design Details}
- The top-level of \TT is taken directly from the
- {\DVI}type\cite{dvitype}\index{DVItype}
- program, with a few
- modifications. Most of the diagnostic functionality of {\DVI}type is
- maintained, but without the user interface (\TT assumes it is supposed to
- process all the pages).
- A ``hook'' was inserted into
- the program to handle the {\TeX}
- |\special|s\index{handling specials}\index{specials, handling by {\TT}}
- that \TT understands
- (hereafter, ``special'' will refer only to those commands that
- \TT understands---other |\special|s are ignored, and simply output
- to the {\DVI} file without\index{specials}
- modification).\index{DVI file}
- The {\DVI}type code was used mostly for its keeping\index{DVI
- position coordinates}
- track of the current {\DVI}\ {\bf h} and {\bf v} position coordinates
- on a page, and handling {\smallrm TFM} information\index{TFM information}.\par
-
- Basically, as \TT slurps in a {\DVI} file, it processes
- ``normal'' commands
- in a normal way (i.e., just keeping track of positions and counters).
- When it reads a |\special| string, it tries to interpret the parameters
- and expand the special, producing
- commands to typeset the graphic using characters from special fonts.
-
- The result is a transformed {\DVI} file that now contains
- ``normal'' (i.e., non-special, `put-that-character-there') dvi-commands
- as far as \TT can tell, after taking care of new font definitions
- and doing any bookkeeping of counters and internal references.\par
-
- \section{Vectors}
- \label{vectors}
- Several design decisions\index{design decisions} were made to give \TT the ability to
- typeset the graphics of the complexity that we desire. This ability is
- intrinsically bound to the fonts to be used, and the way that we use them.
- For this project, I had to create a font of short, oriented line segments\index{vector font}.
- This was to minimize the amount of information required to typeset a
- curve. One could address each pixel of the virtual device to draw the graphic
- (putting hundreds of periods from a font), but that is not
- device-independent, and the
- amount of data is huge in comparison to using line segments.
- These line
- segments can be connected together rather smoothly to give the appearance of
- a continuous line segment or curve.\par
- Using this scheme, described by Nelson
- and Saxe\index{Nelson{,} Bruce}\index{Saxe{,} James}
- at Carnegie-Mellon University\cite{nelson-saxe}, I am able to typeset the correct
- character corresponding to the desired length and angle. I modified their
- font those
- angles cover the first and fourth cartesian quadrant system,
- \index{vector font, range of angles}
- and whose vectors are from the origin to points clockwise along the perimeters
- of semisquares of decreasing radii\label{semisquare}. They use this scheme in order to use the
- longest vectors\index{vector font}\index{vectors, typesetting with}
- possible for a given distance (thus minimizing the number of
- characters to typeset), and also have shorter vectors for use in tightly
- curving lines. They use a semisquare (rather than a semicircle)
- for a quick line-tangent intersection test in their algorithm to decide the maximum
- length vector to use that has a satisfactory variance from the tangent to the
- line.
- I really must give correct thanks to Dario Giuse\index{Giuse{,} Dario}
- at C-MU\cite{dario} for first
- implementing the vector-font typesetting code that I subsequently modified
- for \TTN.\par
-
- I modified the vector font for use with
- Metafont~79\cite{knuth-mf}, and was able to describe it
- in a device-independent manner. Because of the limitations
- of\index{Metafont, limitations}
- Metafont~79's\index{Metafont}\index{vector font, dimensions}
- and {\TeX}'s representation of character heights and depths, I could not accurately
- describe the character dimensions in such a way that I could leave the
- low-level typesetting details to {\TeX}
- through its idea of {\smallrm TFM} information. Thus, \TT has to take
- care of the details of calculating the correct dimensions for each character
- of each vector font. This calculation is done,
- however, only as a particular font is first
- required, and the dimensions\index{vector font, computing dimensions}
- are computed on-the-fly using the group of
- parameters found in the {\smallrm TFM} file that we have defined for our own
- use. After this initial parameter calculation, subsequent references to that
- font's {\smallrm TFM} information is accessible via a caching scheme.
- The fonts contain such information as the measure of the maximum-length
- vector of the font, and the height and width of the pen used to draw the
- font ({\it all in scaled points}). \par
-
- Current plans for the vector fonts are for sizes in the range from about 1
- to 12 ``pixels'' for each of the three types of Metafont pens (circular,
- flat horizontal, and flat vertical).\index{vector font, sizes}\index{vector
- font, types} The fonts are
- actually device-independent in size, as our ``pixel'' is measured in
- absolute units of 16384 $(2^{14})$
- scaled-points\index{vector font, pixelsize}. However, there is a step within
- Metafont~79 that insures that the vector size is an odd-number of
- physical pixels computed at the final output-resolution. This is to avoid
- some discretization errors and the accompanying aliasing artifacts.
- I expect the vectors drawn \index{vector font, pen-types}
- with circular pens (the ``cvec'' fonts)\index{vector font, cvec} to be the
- most utilized. Their
- endpoints are rounded and are positioned to coincide
- so that the segments overlap slightly and
- meet up gracefully producing a smoother curve. Here are some examples of
- circular, horizontal, and vertical pens that can be used for
- different effects:\label{vect-pens}\index{vector font, pens, example}\par
- \noindent\hskip 1in\begintyl{35mm}[1in]
- \special{tyl beginfigure}
- \special{tyl line m 10 c 5 5 10 30}
- \special{tyl line m 10 h 15 5 27 30}
- \special{tyl line m 10 v 30 15 45 23}
- \special{tyl endfigure}
- \endtyl\par
-
- \medskip
- {\bf Beams}\par
- A similar scheme is used for the beam characters found within the music
- fonts\index{beam font}\index{music font}. The beam characters are in two types
- (those for grace notes, and\index{beam font, types}
- those for regular notes) for the staff sizes\index{staff sizes} of music (numbered 0
- down to 8). See also \cite{ross}.\index{beam font, sizes}\label{beam-chars-sizes}
- The font is also a set of short line-segments that will be
- connected to create a beam (some other program will have to know about the
- details of describing how to attach stems from the beams down to the notes).
- However, the beam characters are different\index{beam font, difference from vector font} from the vector fonts in that
- each staff size of music has one particular size of beam
- characters\index{beam font, relation to staff size}
- associated with it.\par
-
- The beams are designed\index{beam font, design} to appear as if they are drawn
- with a flat-edged pen held perpendicular to a ruler (at all orientations).
- When a vertical pen is drawn along a path, the actual cross sectional
- distance of the line segment decreases with the angle (i.e., it is thickest
- when drawn along a line at zero degrees from the horizontal, and thinnest as
- it is drawn along a line approaching $\pm 90$ degrees). The way to maintain
- the appearance of consistent thickness of the line segments at all drawn
- angles is to actually {\it increase\/} the ``height'' of the vertical pen as
- a function of the angle from the horizontal. This function was geometrically
- derived to be the {\it secant\/} of the angle, which yielded in a scaling
- factor to apply to the original definition of the vertical pen's height.\par
-
- Another difference from the vector fonts is that the beam characters do not
- have to cover as large a angular range. The angles from the horizontal are
- less than 45 degrees on the average,\index{beam font, range of angles}
- and the lengths of the beam characters\label{beamsizes}
- are no smaller than the width of a quarter note for that staff size. The
- current implementation defines the beam characters in four groups per staff
- size: regular beams in lengths\index{beam font, lengths}
- of 1.0 and 1.5 quarter-note-lengths, and
- grace-note beams in lengths of 0.5 and 0.66 grace-note-lengths.\par
-
- The scheme
- of typesetting is similar to that of the vectors, but an added constraint is
- resolved. Since the beam characters use a slightly smaller set of fixed angles from
- the horizontal,\index{beam font, constraints}
- we have to choose the best beam character to use such that we use
- the maximum length beam character {\it and\/} try to obtain the least
- deviation from the angle requested to fit the beam font.
- The dimensions of these beam characters
- are computed only as each music font is required, and a caching scheme
- is maintained to avoid unnecessary re-loading of font information and
- subsequent definition in the {\DVI} file. \par
-
- \section{Splines}
- \label{splines}\index{splines, families}A second decision\index{design decisions} that I made
- for the current implementation of this system
- was to use Catmull-Rom\cite{cagd} splines as the default instead of B-splines.\index{splines, default type} The
- reasons for this are two-fold: (1) Catmull-Rom splines\index{Catmull-Rom splines} are of the same
- family as B-splines, but are {\it guaranteed} to produce a smooth curve {\it
- through} the control points, whereas B-splines only approximate within the
- convex-hull described by the control points. Therefore, Catmull-Rom splines
- are a true interpolant; and (2) when dealing with the ties and slurs,\index{ties}\index{slurs} the
- user wants the curve to go through the five points that he specifies (left,
- middle and right points). With B-splines, he would have to {\it estimate}
- the position of the middle control points in order to get the curve to be
- in the correct position. Catmull-Rom and Cardinal splines are just
- as easy to calculate, and usually achieve the effects that we need.\par
-
- I have also experimented with operations on the B-splines to achieve true
- interpolation. This method was described by Barsky and Greenberg\cite{barsky}
- describing how to re-compute B-spline control-points
- so\index{B-splines, recomputing points}
- that the resulting spline would interpolate through desired points (inverse
- interpolation)\index{splines, inversion}\index{splines, interpolation}.
- It actually does not require very hairy mathematics.
- Arcs and circles are implemented\index{arcs, representation}
- using this spline primitive. The arc\index{arcs, control points}
- control-points are computed (or pre-computed in the case of circles,
- \index{circles, control points} and\index{circles, representation}
- ellipses\index{ellipses} which are just scaled circles)
- and then are used in the inversion
- procedure so that the resulting B-spline passes smoothly {\it through\/}
- those original points. We will later describe further this usefulness of
- implementing various graphic objects using lower-level primitives.\par
-
- I also use the Catmull-Rom interpolation when computing the different
- thick\-nes\-ses\index{line thickness} along both the tie/slurs and the var\-iable-thick\-ness splines
- (``ttsplines'')\index{ttspline}\index{ttspline, line thicknesses}.
- I need to interpolate from the current control-point's
- thickness along the curve to the next control-point's thickness, and can do
- this smoothly by using the interpolation methods available when computing
- the splines anyway.\par
-
- Since we have the ability to draw splines of varying thickness, we can
- easily implement ties and slurs\index{slurs} (those long
- arcs connecting groups of notes\index{tieslur, implementation}
- on a musical score), since they are splines of usually five control points,
- having the specified {\it minthick\/} thickness at the left and right, and
- {\it maxthick\/} thickness in the middle. \par
-
- \Makeodd
- E_O_F
- else
- echo "will not over write ./doc/TYLMAN.06"
- fi
- chmod 644 ./doc/TYLMAN.06
- if [ `wc -c ./doc/TYLMAN.06 | awk '{printf $1}'` -ne 11870 ]
- then
- echo `wc -c ./doc/TYLMAN.06 | awk '{print "Got " $1 ", Expected " 11870}'`
- fi
- if `test ! -s ./doc/TYLMAN.08`
- then
- echo "writing ./doc/TYLMAN.08"
- cat > ./doc/TYLMAN.08 << 'E_O_F'
- \chapter{Future Extensions}
- Given a little time, one could extend\index{extensions} the current set of graphic
- primitives in \TTN, such as:
- \begin{itemize}
- \item simpler-appearing macros,
- \item regular polygons (all
- easily built upon currently-existing primitives),
- \item oriented arrows
- \item line-pattern filled figures,
- \item a more general method of defining and instancing symbol definitions.
- \end{itemize}
- I am still experimenting with two
- methods of adequately computing the smoothest interpolation of thicknesses
- along the length of the slur. When the thickness for a particular segment
- of the curve have been determined, we check to see if that thickness is in a
- subset of vector-font sizes. If so, we can use it as-is; otherwise, we have
- to clamp\index{clamping} that thickness to fit in the subset. The only problem is that
- achieving a super-smooth interpolation along the curve's thicknesses might
- require a large number of vector fonts to be loaded---sometimes stressing
- the printing\index{output device} device's capabilities. I still have to experiment to find a
- reasonable subset of these sizes that can be used and still achieve adequate
- results.\par
-
- I wrote this program with the intention of ease
- of extensibility for additional ``primitives'' to be built on top of the
- functionality provided by \TTN.
- I have also interfaced \TT with
- Dario Giuse's\index{Giuse{,} Dario} graphic drawing program
- {\it DP\/} that he
- wrote at C-MU\cite{dario}. It is smart enough to represent its graphics primitives
- in files as a list of text-strings, and is now able to output the |\special|
- strings, specifying the width and height of the created figure.
- Converting the files of the MacDraw program to yield
- {\smallrm ASCII} strings is potentially possible, too.
- In either case, such strings are be easily converted to
- |\special| command strings for \TT to work on.\par
- \Makeodd
- \appendix
- E_O_F
- else
- echo "will not over write ./doc/TYLMAN.08"
- fi
- chmod 644 ./doc/TYLMAN.08
- if [ `wc -c ./doc/TYLMAN.08 | awk '{printf $1}'` -ne 1912 ]
- then
- echo `wc -c ./doc/TYLMAN.08 | awk '{print "Got " $1 ", Expected " 1912}'`
- fi
- if `test ! -s ./doc/TYLMAN.09`
- then
- echo "writing ./doc/TYLMAN.09"
- cat > ./doc/TYLMAN.09 << 'E_O_F'
- \chapter{{\TeX}tyl Summary}
- Let's summarize the abilities and requirements of \TTN . First of all, we
- have to put an |\input{textyl}| near the start of the document (at least
- before our first invocation of a |\special{tyl ...| command). This loads the
- macros that we need to create space for our figure, and to set up the right
- environment for \TTN .\par
-
- Once the macros have been loaded, when we want to set a figure (or even a
- single \TT primitive), we must place the primitives within an environment
- started by
- \hbox{|\begintyl{|\Prm{vertsize}|}[|\Prm{horizsize}|]|}
- and finished by |\endtyl|. Here,
- the required parameter,\Prm{vertsize}, determines the vertical
- size of the box that \TT will create for our figure to be placed in. If we
- do not need extra space, we put in |0pt| or some similar zero-length
- dimension. The optional parameter,\Prm{horizsize}, will add a non-zero width
- to the box that |\begintyl| creates for us. It is {\it crucial\/} that there
- is {\it no\/} space between the |}| and |[| characters of the |\begintyl|
- invocation if we decide to use the optional horizontal width specification.
- Otherwise, things may go awry for this figure. Also, we are responsible for
- any offsets that we may need before the figure is placed. We can achieve
- this through |\hskip| and |\vskip| calls in \TeX\ , or |\hspace| and
- |\vspace| calls in \LaTeX.\index{space}
- \index{{\TeX}}\index{{\LaTeX}}\index{{\TeX} commands}\par
-
- The types of primitives that we may place within the |\begintyl| and
- |\endtyl| pair are summarized here, without their surrounding
- |\special{tyl | -- |}|, nor any extra delimiting punctuation (like commas).
- \begin{verse}
- {\tt beginfigure} \sOpt{meas} \sOpt{xfm}\
- {\leavevmode\hbox{$\>\lbrack${\tt W}$\>\langle wid\/\rangle\,
- \langle ht\rangle\,\rbrack\,$}}
- {\leavevmode\hbox{$\>\lbrack${\tt F}$\>\langle wid\/\rangle\,
- \langle ht\rangle\,\rbrack\,$}} \mbox{\it which opens the environment}
-
- {\tt endfigure}\mbox{\it \ \ which closes the environment}
-
- {\tt line} \sOpt{meas}\sOpt{xfm} \Prm{thick}
- \sOpt{vect}{\leavevmode\hbox{$\>\lbrack${\tt L}$\>\langle style\rangle\,\rbrack$}}
- $ x_{\rm l}\> y_{\rm b}\> x_{\rm r}\> y_{\rm t}$
-
- {\tt spline} \sOpt{meas}\sOpt{xfm}\Prm{thick}
- \sOpt{vect}{\leavevmode\hbox{$\>\lbrack${\tt L}$\>\langle style\rangle\,\rbrack$}}
- \sOpt{spltype}\\
- \hspace*{2em}\sOpt{closure}
- {\leavevmode\hbox{$\>\lbrack${\tt X}$\>\langle thick\rangle\,\rbrack$}}
- \Prm{numpts}\mbox{\it the x-y points}
-
- {\tt ttspline} \sOpt{meas}\sOpt{xfm}
- \sOpt{vect}{\leavevmode\hbox{$\>\lbrack${\tt L}$\>\langle style\rangle\,\rbrack$}}
- \sOpt{spltype}\\
- \hspace*{2em}\sOpt{closure}
- {\leavevmode\hbox{$\>\lbrack${\tt X}$\>\langle thick\rangle\,\rbrack$}}
- \Prm{numpts} \mbox{\it points} \mbox{\it thicknesses}
-
- {\tt arc} \sOpt{meas}\sOpt{xfm} \Prm{thick}\sOpt{vect}
- {\leavevmode\hbox{$\>\lbrack${\tt L}$\>\langle style\rangle\,\rbrack$}}\Prm{radius}\\
- \hspace*{2em}{\leavevmode\hbox{$\>\lbrack${\tt @}$\>\langle cent_x\rangle\,
- \langle cent_y\rangle\,\rbrack$}}\Prm{startAng} \Prm{stopAng}
-
- {\tt label} \sOpt{meas}
- \Prm{face}$\;x \> y$ \mbox{{\tt "}\Prm{string}{\tt "}}
-
- {\tt tieslur} \sOpt{meas} \Prm{minthick}\Prm{maxthick}
- \Prm{numpts}\mbox{\it points}
-
- {\tt beam} \sOpt{meas} \Prm{staffsize}
- \sOpt{beamtype} $x_1 \> y_1\> x_2\> y_2$
-
- where:
- \end{verse}
- \begin{description}
- \item[meas] specifies units of length for this primitive. One of |S|,|P|, or
- |M| indicates scaled-points, printers-points, and millimeters, respectively.
- Defaults to printers-points.
-
- \item[xfm] specifies a transformation to be applied. It is of the form\\
- \mbox{{\tt T}\Prm{sx}\Prm{sy}\Prm{tx}\Prm{ty}\Prm{rot}}, where {\it sx\/} and
- {\it sy\/} are for scaling, {\it tx\/} and {\it ty\/} are for translation,
- and {\it rot\/} is for counter-clockwise rotation (in degrees).
-
- \item[thick] is the integer thickness of the line. Usually between 1 and 12.
-
- \item[vect] is the type of vector font to use. One of |C|, |H|, or |V|
- indicates circular, horizontal-flat, or vertical-flat pen type. Defaults to
- circular pen.
-
- \item[style] is the line-style to use. One of |0|, |1|, |2|, or |3| indicates
- a solid, dotted, dashed, or dot-dashed line-style. Defaults to solid line.
-
- \item[spltype] is the kind of spline to use through the control points. One of
- |B|, |D|, |K|, or |I| indicates the B-spline, Cardinal, Catmull-Rom, or
- Interpolating b-spline basis to use, respectively. Defaults to Catmull-Rom.
-
- \item[closure] is one of |O| (``oh'') or |U| which indicates that the spline
- is closed or open, respectively. Defaults to open.
-
- \item[numpts] is the integer number of control points for this spline.
-
- \item[radius] is the length of the radius in units specified by \Prm{meas}.
-
- \item[centx] and {\bf centy} are the center-point coordinates
- of the arc/circle.
-
- \item[startAng] and {\bf stopAng} are the initial and final angles,
- respectively, for the arc as measured in degrees counter-clockwise from the
- positive x-axis. If they are the same number, a closed circle is indicated.
-
- \item[face] refers to the style of typeface for the label.
- See page~\pageref{labelfonts} for the list.
-
- \item[string] is the string-body of the label to typeset at the specified
- position.
-
- \item[staffsize] refers to the staff note-size for beams. It is between 0
- and 8, inclusive.
-
- \item[beamtype] is the type of beam to use. One of |G| or |R| indicates
- grace-note size, or regular size beams, respectively. Defaults to regular.
-
- \item[wid] and {\bf ht} refer to the width and height of a figure, in units
- specified by \Prm{meas}. Mainly used in conjuction with |F| (``Fitting''
- size operator) and |W| (``Written'' size marker).
- \end{description}
- \Makeodd
- E_O_F
- else
- echo "will not over write ./doc/TYLMAN.09"
- fi
- chmod 644 ./doc/TYLMAN.09
- if [ `wc -c ./doc/TYLMAN.09 | awk '{printf $1}'` -ne 5644 ]
- then
- echo `wc -c ./doc/TYLMAN.09 | awk '{print "Got " $1 ", Expected " 5644}'`
- fi
- if `test ! -s ./doc/TYLMAN.07`
- then
- echo "writing ./doc/TYLMAN.07"
- cat > ./doc/TYLMAN.07 << 'E_O_F'
- \chapter{The Implementation}
- \section{Overview}
- \TT is currently nearly 9000 lines of Pascal code (not {\smallrm WEB}). It is
- a prototype, and {\it not} a product.
- Testing was simplified by the ability to pre-view\index{DVI file, previewing} the contents of the
- {\DVI} file on Sun workstations using the {\smallrm DVISUN}
- \index{DVISUN}\cite{dvisun} program. It was written using
- Berkeley Unix\footnote{Unix is a trademark of Bell Laboratories}\index{Unix}
- Pascal\index{Pascal}, but is not dependent on that operating system
- except for
- differences in I/O. There are also differences in
- efficiency/ease of reading from files---{\tt read}s versus {\tt get}s. I/O
- routines for both byte types (signed and unsigned)
- are written and available, and have been set up
- for easy porting to other machines.\par
-
- The idea for handling {\DVI} files is to read each byte
- into a buffer until we read an {\tt eop} (end-of-page marker), when we will
- write that buffer out into a file, and start a fresh buffer with the next
- page. If we encounter a |\special| in our reading, we treat it as a
- \index{specials, handling}\index{macro-expansion}
- macro-expansion---substituting {\it our} byte-string for the byte-string
- that represented the invoked special, and put this ``tyled''\index{tyling} string into the
- buffer for subsequent output. A nice feature of this slurping is the parser
- for the specials. It is simple and extensible enough to easily accommodate
- new \TT primitives, and different or additional parameters.\par
-
- Besides being careful about the expansion of the |\special| string, \TT
- has to keep track of any newly-defined fonts for insertion into the
- {\tt postamble} in the {\DVI} file, and do some bookkeeping for
- {\tt bop} backpointers, and file byte-length.\par
-
- Most of this chapter discusses the
- algorithms and data-structures of \TT at various levels.
- We'll start with the high-level and user concepts, and work our way down
- into the details of outputting the actual bytes into the {\tt .dvi} file.\par
-
- \section{Primitives}
- The user's interface to \TT is through |.tex| text files.\index{{\tt .tex}
- text file}
- He types in the |\special| strings for {\TeX},\index{{\TeX}}
- and fills in the name of the primitive to typeset
- and any parameters to modify the attributes of the
- primitive. This |.tex| file is converted by {\TeX} into a |.dvi| file which
- is then given to \TTN.
- \index{primitives, modifying attributes}
- For the most part, all of the graphic primitives\index{primitives}
- in \TT have common attributes
- of\index{primitives, attributes}\label{prims-attribs}
- \begin{itemize}
- \item bounding-box\index{bounding box},
- \item line thickness,
- \item pen-type (see section~\ref{vect-pens}),
- \item line style\index{line style}
- \end{itemize}
- that describe basic appearances of an item. A ``bounding-box''
- \index{bounding box} describes the
- minimum and maximum $X$ and $Y$ values of a minimum-sized
- orthogonal rectangle that encloses the primitive.
- I'll describe the primitives and
- point out their additional or modified attributes to those above. My plan
- was to provide a number of primitives that were conceptually built upon
- lower-level primitives, and share similar representations wherever possible.
- For example, a |tieslur| is clearly built upon the representation\index{tieslur, representation} of a
- spline primitive. With this concept, I was able to represent the following
- primitives and effectively ``draw'' them by reducing to easier primitives,
- \index{primitives, reduction of} down to the vector-font level.\par\filbreak
- \medskip
- \noindent{\bf Line}\par
- The most basic primitive is the |line|, as all other non-figure
- primitives\index{line segments}\index{{\tt line}}
- reduce to the same routines that produce line-segments. A line has
- attributes of bottom-left and upper-right endpoints,
- and is drawn from left to right in {\DVI}-space, which is similar to
- fourth-quadrant cartesian space, but $y$-values are positive-increasing going down the
- y-axis\index{DVI-space}. In section~\ref{vect-setting} I will describe how the line is
- ``drawn'' on the virtual page using the vector-font characters.\par
- \medskip
- \noindent{\bf Spline}\par
- The spline primitives (|spline| and |ttspline|) have the attributes of a
- \index{splines, attributes}
- line, and in addition:\index{{\tt spline}}\index{{\tt ttspline}}
- \begin{itemize}
- \item spline type (see section~\ref{splines}),
- \item openness,
- \item a count, and a list of control-points.
- \end{itemize}
- The spline primitives all use the same basic algorithm for interpolation of
- its control-points (``knots'') using one of three spline bases: the B-spline
- basis, the Cardinal basis, and the Catmull-Rom basis. The difference is mainly
- in the choice of basis matrix.\index{splines, basis}\index{splines, B-spline}
- \index{splines, Catmull-Rom}\index{splines, Cardinal}\par
-
- |Ttspline|s have an additional attribute that describes the thickness of the
- spline at each control point. \TT uses the same method of
- spline\index{{\tt ttspline}}
- interpolation for computing the varying thicknesses over the length of the
- spline as for computing the position of the line-segment positions over the
- spline.\par
- \medskip
- \noindent{\bf Ties}\par
- A |tieslur|\index{{\tt tieslur}} is just a subset of
- ttsplines\index{tieslur, relation to ttsplines}. It has exactly $5$
- control-points,\index{tieslur, attributes}
- which is sufficient to describe even the longest slur. It needs two
- specified line thicknesses: (1) a minimum thickness value at the far end points,
- and (2) a maximum thickness in the middle of the slur. \TT uses an internal
- algorithm to figure the other thicknesses of the control points. This then
- reduces to a ttspline of five control points for interpolation. The only
- other difference from a |ttspline| is in the
- ``clamping'' mechanism\index{splines, clamping}\index{clamping}\index{ttspline, clamping}\index{tieslur, clamping}.
- Let me explain: optimally, we would like the smoothest possible transitions
- of line thicknesses along a varying thickness spline, but this is still
- subject to the aliasing artifacts
- (``stair-steps'',\ ``jaggies'')\index{jaggies} of the printing device's
- resolution (you can't have 3.3 pixels in black and white). We could have a
- vector font for every possible pixel-size of the printer, and thus be able
- to achieve as smooth a line as the printer is capable. This could easily
- require the printer to use dozens of different fonts per page (imagine a
- page of math, text, and a complex figure) which most printers' limited font
- memories\index{output device, font memory} cannot handle\par
- We are faced with either not being able to print the page (sort of
- defeating the whole purpose), or to reduce the number of fonts required to
- set that particular figure. This reduction is called ``clamping.'' We make
- sure that a requested vector size is in a pre-selected set of fonts, and
- then modify that size if it is not in that set. Usually this involves just
- adding/subtracting a vector-pixel unit and iterating again through the test-modify
- loop until the size fits.\par
-
- Ties and slurs use the same basic clamping mechanism as |ttspline|s
- (described above), but also have a built-in way to select and compute the
- thicknesses along the length of the spline. This means that \TT decides the
- thicknesses for the tie/slur using its own algorithm based on the user
- specifying the maximum and minimum thicknesses.\par
-
- \medskip
- \noindent{\bf Arcs}\par
- |Arc|s \index{{\tt arc}} are described\index{arcs, attributes} in terms of a radius, an initial and
- final angle, and an optional center coordinate. Internally, this is
- transformed into a uniform-thickness spline.\index{arcs, representation}
- Closed circles are a special
- case\index{circles} of arcs,\index{circles, relation to arcs}
- \index{arcs, circles} and so we can pre-compute
- the control points of the closed spline\index{arcs, closed splines} to describe the
- circle,\index{circles, control points} and then just scale to fit the desired
- radius and translate its center to the required coordinate. Ellipses,
- \index{arcs, ellipses} \index{ellipses} although not a named primitive, can
- be simulated effectively by specifying a closed arc (a.k.a\ circle) and
- \index{ellipses, relation to circles}
- transform it by scaling as desired in either $X$ and/or $Y$, since circles are a
- special case of ellipses.\par
-
- Open arcs are represented by an open spline\index{arcs, open}\index{arcs, open spline} whose control
- points were computed\index{arcs, control points} by sampling along the length
- of the arc. We do this sampling in 16 places using the parametric
- representation of the arc:
- $$x = r \cos\theta \> {,}\>\> y = r \sin\theta \qquad
- {\rm\ for\ } \alpha_1 \le \theta \le \alpha_2 $$ and
- $\theta$ is a multiple of ${1\over 16} (\alpha_2 - \alpha_1)$. After we obtain
- these control points, we can interpolate over the knots and obtain the
- spline segments.\par
-
- In reality, we have to treat arcs with a little more special care
- than simple splines. In computing open splines, we have to do some tricks
- with the list of control points. We introduce ``phantom'' control
- points
- which help the endpoints look nicer. See \cite{wu-abel} for a better explanation
- of phantoms\index{phantom control points}. The problem with arcs is that the
- \index{arcs, phantoming}endpoints would look too ``flat'' if we used the normal phantom-ing method\index{phantoming}.
- What I do is to create two extra control points (one before the start of the
- actual arc, and one after) so that we preserve roundness by continuing
- around the arc with the same parameters to the representation. Then I {\it
- lie\/} to \TT 's innards, saying, ``these extra points are not really part
- of the arc to typeset. They are the phantoms, so don't compute any for
- us.''\index{lies} After that, everything else works pretty much the same as
- regular open-splines in ``tyl''-ing\index{tyling}. It should be apparent that splines are
- the largest class of primitive types that \TT deals with, since they are
- capable of simulating/representing most graphical objects that we ususally
- work with.\index{splines, use in simulating}\par
- \medskip
- \noindent{\bf Beams}\par
- The last basic primitive that \TT offers is the |beam|. Beams\index{{\tt beam}} are
- graphically equivalent to straight line-segments. The only difference
- is\index{beams, difference from lines}
- that they have a different font that they use. This font and the particular
- characters from it are determined by the beam's two attributes:\index{beams, attributes} staffsize
- and beam-type. Staff size refers to the spacing of the staff lines of
- a\index{staff sizes}\index{staff lines}
- music score, which also determines the size of the music symbols to use. It
- is analagous to defining the point size of a character given the interline
- spacing measure. See \cite{ross} for examples of each size, also the
- discussion of the beam characters on page~\pageref{beam-chars-sizes}. The
- beam-type attribute refers to the size of notes that the beam connects:
- regular or grace notes. More will be said about beams in
- section~\ref{beam-setting}.\par
- \medskip
- \noindent{\bf Labels}\par
- |Label|s\index{{\tt label}} are not really considered primitives, but are included
- here for convenience and completeness. They have no correspondence
- with any of the other graphic-primitives described above, but may be
- included in figure definitions.
- Labels have the attributes of starting position, font-style, and
- the string-body of the label. They are not transformable at the
- local level (but are affected by figure-level transforms),
- and are basically pretty simple in nature. {\TeX} macros are not expanded
- within the string-body by \TTN; you should use {\TeX} do to any
- smarter label-typesetting.\par
- Currently, the built-in list of fonts selectable for
- use\index{fonts, for labels}\index{labels, font face-styles} in placing
- labels is:\label{labelfonts}
- \begin{itemize}
- \item amtt10 (selectable by specifying face |1|)
- \item amb10 (face |2|)
- \item amsl10 (|3|)
- \item amtt8 (|4|)
- \item and amsl8 (|5|)
- \end{itemize}
- The characters from these fonts are simply set, as \TT does not
- worry about kerning or ligatures, and spacing is done with
- information found in the parameter section of the |.tfm| file.
- This font mapping list is only temporary, and
- can be changed within the \TT source program.\par
-
- \section{Procedural Handling}\label{proc-handling}
- After \TT picks apart the |\special| strings\index{special} from the {\DVI} file,
- and determines the parameters (both specified and defaulted) for the specified
- primitive, \TT makes a note about where in the file the start of the special
- occurs, and passes the data to a {\it handler}.\index{handlers} A handler is
- a procedure that is specific to each primitive (e.g., there is a
- |linehandle|,\index{handlers, linehandle} and a |ttsplinehandle|
- procedure\index{handlers, ttsplinehandle}) that knows about the internal
- representation of each primitive, and how to ``handle'' the data passed to
- it. We'll talk more about the internal representation in the next
- section.\par
-
- The handlers' primary responsibility is to take care of primitive-level
- geometric transformations, and then to decide what to do with the data,
- depending on the context of\index{handlers, functionality}
- the primitive being dealt with. This context is determined by whether the
- primitive is contained in a figure, or is by itself. If the primitive is
- {\it not}
- contained in a figure (i.e., the |\special| string was not within a
- |beginfigure| -- |endfigure| pair), the handler
- \begin{enumerate}
- \item computes the bounding box for the primitive\index{bounding box},
- \item transforms the
- coordinates of the primitive into {\DVI}-space\index{DVI-space},
- \item offsets them by the current position on the page,
- \item outputs a {\DVI} |push| command,\index{{\tt push}}
- \item calls an appropriate procedure to actually typeset the primitive,
- \item and finishes with a |pop| command.\index{{\tt pop}}
- \end{enumerate}
- We need to transform coordinates from our first-quadrant cartesian space
- into {\DVI}-space because the lower-level procedures that actually
- typeset and output the vector characters assume that they are putting the
- characters onto a page of the {\DVI} file.\index{transform to DVI space}\par
-
- If the primitive's definition is part of an enclosing figure definition, we
- delay output of this primitive until the figure is completely defined. The
- handler does any simple geometric transformations required, and then
- simply packs the data into another structure, and sort of ``stacks'' this
- new structure (let's call it an {\it item}\index{item}) onto a list of items
- that are contained in this figure. Our reference to ``figure''
- here could also be a sub-figure within an enclosing figure, but for now
- we'll just deal with primitives in terms of simple, one-level figures. When
- the figure definition is complete, the |figurehandle|
- procedure\index{handlers, figurehandle} is called. We will get into figures
- more in the next section, but for now, we'll say that this handler
- \begin{enumerate}
- \item computes the bounding box of all the sub-items of this figure,
- taking care of necessary transformations,
- \item outputs a |push| command,
- \item unpacks each sub-item, and transforms its coordinates into {\smallrm
- DVI}-space,
- \item calls the item's particular primitive handler with a special flag
- that says to simply call the appropriate procedure for immediate typesetting
- without doing any further transforms,
- \item and finishes with outputting a |pop| command to the {\DVI}
- file.
- \end{enumerate}
- The design of these handlers was to maintain the idea
- of\index{handlers, design idea}
- ``information-hiding'' such that each handler (primitive- or figure-level)
- would know only about one level of abstraction below it.\par
-
- \section{Figures}
- Let's look more closely at what we called ``items'' \index{item}in the previous section,
- and how we really represent figures. Up to this point, I have been rather
- ambiguous when referring to ``primitives.''\index{primitives, definition of} In some cases, it meant
- {\it graphic-primitives\/} (like lines and splines); in other cases it meant
- {\it the things that we can make pictures with\/} (like figures, sub-figures,
- and graphic-primitives). Well, now the ambiguity gets worse. I'll try to be
- careful about distinguishing ``graphic-primitives'' when I mean primitives that
- are reducible to vector characters, and use ``primitives'' when I mean
- graphic-primitives {\it and\/} figures. The reason for
- the difference is that since we have the ability to do recursive sub-figure
- definitions, a ``figure'' (as denoted by a |beginfigure|--|endfigure| pair)
- becomes a building block (just like graphic-primitives) for
- that enclosing figure's definition. It is analagous to the programming
- language concept of \Prm{block}, where (in BNF notation)
- \vspace*{-10pt}\begin{verbatim}
- <figure> ::= <primitive> / <primlist>
- <primlist> ::= <beginfigure> <primlist> <endfigure> /
- <primitive> <primlist> / <empty>
- \end{verbatim}
- where \Prm{primitive} is what we previously referred
- to as an ``item,''\Prm{beginfigure} is
- denoted by |\special{tyl beginfigure}|, and
- \Prm{endfigure} is denoted by |\special{tyl endfigure}|. Refer back
- to page~\pageref{sub-figures} for an example of sub-figures.\par
-
- \medskip
- \noindent{\bf Items}\par
- The ``item'' data structure contains the attributes for graphic-primitives,
- as outlined in section~\ref{prims-attribs}, and also contains
- attributes for a figure like:
- \begin{itemize}
- \item any figure-level transformation parameters,
- \item a ``name,''
- \item and the list of items contained in this figure.
- \end{itemize}
- As you may surmise, this can yield a linked-list of linked-lists when built
- to represent a complex nested figure. In our previous discussion of
- handlers, one mode of their operation was to ``pack and stack'' the data
- into an item. Packing\index{item, packing} is easy enough to understand, but putting this
- structure in the correct place is tricky. When an item is created and filled
- with the appropriate parameters in a graphic-primitive's handler, there is a
- notion of ``context''\index{figures, context} which refers to the depth of recursion
- of sub-figures. A depth of $0$ means that there is no higher-level figure, a
- depth of $1$ means that any primitives encountered will belong to an
- outermost level figure, etc. When \TT comes across a |beginfigure| special
- string, it changes the recursive-definition context, and names that figure
- with that depth number. After that, any graphic-primitives that are
- encountered belong to that named figure in that context. An |endfigure|
- special will decrement the depth of recursion, and thus will change context
- back to the previous context. If this new context has a depth of $0$, then
- we know we have closed the outermost level of figure definition, and thus
- we are ready to typeset the entire figure.\par
-
- Let's look at how items are inserted\index{item, inserting} onto our data structure so that context
- is maintained. \TT uses a procedure called |pushItem| that takes an item and
- puts it on the correct list (or sub-list) according to the current figure
- context. Roughly, the algorithm is a simple insert, based on a key of
- depth-name.
- \begin{tabbing}
- \hskip 1cm \= Start from the front of the list of this figure\\
- \> while \= the list is not empty\\
- \> \> Look \= at the item\\
- \> \> \> if it is \= a figure of the current context\\
- \> \> \>\> then we are done searching. do an insert\\
- \> \> \> otherwise {\it there must be a sub-figure lower on the
- list}\\
- \> \> \> \> look for the next item on the list that is a figure\\
- \> \> \> \> and start the next search from its list
- \end{tabbing}
- I really simplified the explanation of the
- insertion scheme here, but the important idea is that of looking for the
- correctly labelled figure-list and inserting the item there.\par
-
- Once the structure is built, and \TT determines that it is ready to typeset
- the entire figure, it traverses\index{item, traversing} the structure to compute and note the
- bounding boxes of the sub-figures (and their bounding boxes, too).\index{bounding
- box}
- We need to do this in case there are any\index{transforms, figure-level}
- figure-level scaling or rotations of graphic-primitives which are performed relative
- to the center of the bounding box of the primitives contained in the
- figure. As we traverse the sub-figures, we do any required sub-figure
- transforms, record the dimensions of the bounding box, and pop up a level.
- When our traversal has reached the top level, all the figure's primitives
- have been transformed according to the recursive definition's specifications
- (i.e., the transforms are additive as we descend in recursive
- depth).\index{transforms, additiveness} If there are any top-level transforms
- to be taken care of,\index{transforms, top-level} we revisit the lists of
- primitives, performing the transforms.
- Finally, at
- this point we are ready to re-traverse the structure, grab each
- graphic-primitive, unpack it, transform it into {\DVI}-space,
- and give control to its handler for immediate typesetting.\par
-
- If you really want to get picky, the contents of a figure are not
- typeset and output until the last balancing |endfigure|\index{{\tt endfigure}} is encountered. It
- is at the current position on the page where this |endfigure| is set that
- the origin of our figure is placed. We can get away with this condition
- because specials are viewed by {\TeX} as ``boxes'' of zero width, and so a consecutive series of
- |\special|s do not change the current position on the page relative to the
- first invocation of the list. If, however, the user types in normal
- {\TeX}-typesettable text in the middle of a list of |\special|s defining a
- figure, the current position will move, and our figure will be shifted down
- to the position where the final |endfigure| is invoked. This might make him
- unhappy. My advice is to think of the figure/picture as an atomic entity,
- whose contents is strictly a list of |\special| strings defining that
- figure.\par
-
-
- \section{The Fonts}
- The whole basis of this program lies in the ability to typeset graphics with
- characters. Thus we have two families of fonts: the vector fonts (originally
- designed at C-MU\cite{nelson-saxe} by Bruce Lucas\index{Lucas{,} Bruce}),
- and the beam fonts (part of the music
- fonts for the {\it MusiCopy\/}\index{MusiCopy} project).\par
-
- \TT converts the requests for line-drawings into commands to typeset these
- characters of line segments. See Appendix~\ref{font-examples}
- for examples of these characters. Since Metafont~79\index{Metafont} limits the {\smallrm
- TFM} information to 16 heights and depths, we have to do the computations of
- the character dimensions ourselves.\index{fonts, computing dimensions of}
- This is easy to do as \TT has the
- correct dimensions for each character described in Pascal code in such a way
- that only a couple parameters from the {\tt .tfm} file need to be accessed
- in order for the code to define the exact (internal) dimensions for a font.
- In essence, the basic description of the vector and beam fonts are
- hard-coded in \TTN , in a manner independent of the actual size of the
- pens used to draw them.
- This ``on-the-fly'' font calculation is done only as needed, and then the
- font information is cached and noted so that future requests for that font
- will not require us to re-compute these dimensions.\par
-
- Within the modified {\DVI} file,
- \TT defines these new fonts and begins numbering from 300,\index{fonts,
- numbering} as a sort of
- ``signature.''\index{{\TT}, signatures} So if you look at this new
- {\DVI} file with {\smallrm DVI}type, you can tell the parts that are typeset
- figures by noting the places in the listing that reference a font numbered
- above 300.\par
-
- \subsection{Vector Setting}\label{vect-setting} The vector fonts themselves,
- as described in section~\ref{vectors}, are typeset using the method
- described by Nelson\cite{nelson-saxe}, and I'll describe how \TT does it. In
- section~\ref{proc-handling}, we made mention that a graphic-primitive's
- handler call an ``appropriate procedure to actually typeset the primitive.''
- This typesetting procedure is actually the ``hook''\index{programmer's hook}
- for a programmer to get right to the typesetting code. The procedures look
- like |Tyl|$x$, where $x$ is a graphic primitive (e.g., |TylSpline|,
- |TylArc|, etc.), and take as parameters the information equivalent to the
- unpacked representation of an item. The coordinates of any points
- used are in {\DVI}-space, \index{DVI-space} and in units of
- scaled-points. Refer to the code for the formal parameter
- list of each |Tyl|$x$ procedure. These hooks call procedures to ``lay''
- line-segments
- on the page, after doing some work of clamping\index{clamping}, and opening
- the correct font files for the requested
- line-thickness\index{line thickness} (thickness{\underbar es} in the case
- of |ttspline|s). These procedures, in turn, call |layline|,\index{{\tt
- layline}} a procedure that determines the best way to typeset the
- line-segment. |Layline| checks to see if the line is strictly horizonal or
- vertical so that it can reduce the line to typsetting a {\TeX} rule, and
- then just add endpoints for smooth overlap. However, if the line is more
- diagonal, we have to go through more work.\par
-
- Diagonal lines, and certain cases where we think using {\TeX} rules
- inappropriate, require potentially using the full set of vector characters.
- The |diagonal| procedure intersects the line-segment with the origin of
- the semi-square
- of the vector font (see also page~\pageref{semisquare}). In essence, it
- implements a greedy method by scaling down the radius of the semi-square to find
- the longest possible radius of the vector characters such that the far point
- of the line-segment lies just outside that radius.\par
- \noindent
- \begin{figure}[h]\hskip 4cm\begintyl{8cm}[1in]
- \special{tyl beginfigure}
- \special{tyl line m 2 0 70 32 70}
- \special{tyl line m 2 32 70 32 6}
- \special{tyl line m 2 0 6 32 6}
- \special{tyl line m 2 0 55 16 55}
- \special{tyl line m 2 16 55 16 22}
- \special{tyl line m 2 16 22 0 22}
- \special{tyl line m 2 0 46 8 46}
- \special{tyl line m 2 8 46 8 30}
- \special{tyl line m 2 0 30 8 30}
- \special{tyl line m 2 0 42 4 42}
- \special{tyl line m 2 4 42 4 34}
- \special{tyl line m 2 0 34 4 34}
- \special{tyl line m 2 0 40 2 40}
- \special{tyl line m 2 2 40 2 36}
- \special{tyl line m 2 0 36 2 36}
- \special{tyl line m 2 0 38 32 38}
- \special{tyl line m 8 0 38 25 54}
- \special{tyl endfigure}\endtyl
- \caption{Semi-squares of the Vector Fonts}
- \end{figure}
- \noindent Then |diagonal|
- determines the $dy$ and $dx$ from the current position to that intersection
- point on the line.\footnote{Thus $dx$ and $abs(dy)$ are integer powers of 2
- between 0 and 16 inclusive.}
- We use the mapping \index{vector font, mapping function}
- function similar to \cite{nelson-saxe} to determine character code corresponding to these
- $dy$ and $dx$ values:\goodbreak
- \vspace*{-10pt}
- $$ code = 160 + dy + dx - 9*{\rm max}\,(dx,\, -dy)\qquad {\rm\ for\ } dy < 0 \> {,
- }\>\> dx \geq 0$$
- $$ code = 160 + dy - dx - 7*{\rm max}\,(dx,\, dy)\qquad {\rm\ for\ } dy \geq 0 \> {,
- }\>\> dx \geq 0$$
- but this scheme assumes that our font has at least 160 characters (i.e.,
- 256), but most fonts have only 128 characters. We have to re-map this
- discontinuous set of codes to fit with a range of $0 \ldots 127$, and in doing so,
- we have to lie\index{lies} about two of the characters by pretending that
- the two longest vertical vectors do not exist, but each is
- to be replaced by {\it two\/} vectors of half that length.\par
-
- Once we have determined the vector character, all we have to do is move to the
- current-position, set the character, increment our position,
- and finish setting the rest of this line-segment. The
- thickness of the vector theoretically does not matter, as the path followed
- by the vector character is invariant over the thickness (at least to the
- resolution of the printer).\index{vector font, path invariance}\par
-
- \subsection{Beam Setting}\label{beam-setting}
- The way that \TT typesets beam is similar to typesetting
- line-segments.\index{beams, typesetting}
- The
- |TylBeam| procedure takes care of determining the correct beam character to
- use. Recall from section~\ref{beam-chars-sizes} that there are two lengths
- for each type of quarternote (i.e., regular notes and grace notes). When \TT
- tries to typeset the beam, it uses the beam character whose length is
- longest {\it and\/} whose angle is closest to that required.\par
-
- Given a music font of beam characters with their lengths, heights, depths,
- and angles from horizontal computed, we try to set the whole beam at once by
- the following method:
- \begin{enumerate}
- \item Compute the $dy$ and $dx$ of the beam, as well as its length and
- actual angle from horizontal
- \item compute the fractional number of characters needed to typset the beam
- for both sizes of beam characters (this is
- ${{\rm length}_{\rm beam}\over {{\rm length}_{\rm beamchar}}}$)
- \item try to bracket a pair of beam characters whose angles are nearest the
- actual angle of the beam
- \item use the beam character that has the smallest angular deviation from
- that of the actual beam
- \item typeset the characters along the line from the left
- endpoint of the beam to as close to the right endpoint as possible. Then
- typeset the last character such that the right-hand-side of the character
- coincides with the right endpoint of the beam.
- \end{enumerate}
- We only need to select one character to use for typesetting as the
- slope of the beam is constant over its length, and the character used has a
- ``slope'' (angle from horizontal) that is as close as possible to the
- beam.\par
- This juggling of ``best-length'' versus ``best-slope'' is only necessary
- because of the need to keep the set of characters to a reasonable size, and
- also because the angles required for beams is not as broad as for the
- requirements of the more-general vector line-segments.\par
-
- \section{Buffering}
- As \TT reads in bytes from the {\DVI} file for subsequent interpretation, it
- copies them
- into an internal buffer. At a simple level, this buffer is used to simply
- copy the {\DVI} bytes used on a {\DVI} page (delimited by |bop| and |eop|
- bytes). Thus, \TT would act simply as a mechanism that copies its input to
- its output, verbatim. At the level that {\it we} are interested in, this
- buffer will hold all the bytes up to, and including a |tyl| special string.
- On page~\pageref{proc-handling}, we made mention of a ``note about where the
- start of the special occurred'' in the {\DVI} file. When we read
- a\index{specials}\index{tyling}
- |special|, we mark the position of the beginning byte of the special, as
- found in our buffer. If we find that the special is ``tyl''-able, we back up
- the current place in the buffer to the start of the special, and proceed
- with the tyling. \TT will output typesetting command bytes, and effectively
- over-write the previous |special| string in the buffer, achieving a kind of
- in-line macro-ex